<%!
import pprint
def prettify(x):
    try: 
        out = pprint.pformat(x)
    except Exception, e: 
        out = '[could not display: <' + e.__class__.__name__ + \
              ': '+str(e)+'>]'
    return out
%>\
<%page args="exception_type, exception_value, frames, handler, out"/>\
<%def name="dicttable_items(items, kls='req', id=None)">
    %if items:
        <table class="${kls}" ${id and 'id="%s"' % id or ""}>
        <thead><tr><th>Variable</th><th>Value</th></tr></thead>
        <tbody>
        %for  k, v in items:
        <tr><td>${k |h}</td><td class="code"><div>${prettify(v) |h}</div></td></tr>
        %endfor
        </tbody>
        </table>
    %else:
        <p>No data.</p>
    %endif
</%def>\
<%
    def dicttable(d, kls='req', id=None):
        items = d and d.items() or []
        items.sort()
        dicttable_items(items, kls, id)
        return ""
%>\
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en">
<head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
  <meta name="robots" content="NONE,NOARCHIVE" />
  <title>${exception_type |h} at ${handler.request.path_info |h}</title>
  <style type="text/css">
    html * { padding:0; margin:0; }
    body * { padding:10px 20px; }
    body * * { padding:0; }
    body { font:small sans-serif; }
    body>div { border-bottom:1px solid #ddd; }
    h1 { font-weight:normal; }
    h2 { margin-bottom:.8em; }
    h2 span { font-size:80%; color:#666; font-weight:normal; }
    h3 { margin:1em 0 .5em 0; }
    h4 { margin:0 0 .5em 0; font-weight: normal; }
    table { border:1px solid #ccc; border-collapse: collapse; width:100%; background:white; }
    tbody td, tbody th { vertical-align:top; padding:2px 3px; min-width: 120px; }
    thead th { padding:1px 6px 1px 3px; background:#fefefe; text-align:left; font-weight:normal; font-size:11px; border:1px solid #ddd; }
    tbody th { width:12em; text-align:right; color:#666; padding-right:.5em; }
    table.vars { margin:5px 0 2px 40px; }
    table.vars td, table.req td { font-family:monospace; }
    table td.code { width:100%; }
    table td.code div { overflow:hidden; }
    table.source th { color:#666; }
    table.source td { font-family:monospace; white-space:pre; border-bottom:1px solid #eee; }
    ul.traceback { list-style-type:none; }
    ul.traceback li.frame { margin-bottom:1em; }
    div.context { margin: 10px 0; }
    div.context ol { padding-left:30px; margin:0 10px; list-style-position: inside; }
    div.context ol li { font-family:monospace; white-space:pre; color:#666; cursor:pointer; }
    div.context ol.context-line li { color:black; background-color:#ccc; }
    div.context ol.context-line li span { float: right; }
    div.commands { margin-left: 40px; }
    div.commands a { color:black; text-decoration:none; }
    #summary { background: #ffc; }
    #summary h2 { font-weight: normal; color: #666; }
    #explanation { background:#eee; }
    #template, #template-not-exist { background:#f6f6f6; }
    #template-not-exist ul { margin: 0 0 0 20px; }
    #unicode-hint { background:#eee; }
    #traceback { background:#eee; }
    #requestinfo { background:#f6f6f6; padding-left:120px; }
    #summary table { border:none; background:transparent; }
    #requestinfo h2, #requestinfo h3 { position:relative; margin-left:-100px; }
    #requestinfo h3 { margin-bottom:-1em; }
    .error { background: #ffc; }
    .specific { color:#cc3300; font-weight:bold; }
    h2 span.commands { font-size:.7em;}
    span.commands a:link {color:#5E5694;}
    pre.exception_value { font-family: sans-serif; color: #666; font-size: 1.5em; margin: 10px 0 10px 0; }
  </style>
  <script type="text/javascript">
  //<!--
    function getElementsByClassName(oElm, strTagName, strClassName){
        // Written by Jonathan Snook, http://www.snook.ca/jon; 
        // Add-ons by Robert Nyman, http://www.robertnyman.com
        var arrElements = (strTagName == "*" && document.all)? document.all :
        oElm.getElementsByTagName(strTagName);
        var arrReturnElements = new Array();
        strClassName = strClassName.replace(/\-/g, "\\-");
        var oRegExp = new RegExp("(^|\\s)" + strClassName + "(\\s|$$)");
        var oElement;
        for(var i=0; i<arrElements.length; i++){
            oElement = arrElements[i];
            if(oRegExp.test(oElement.className)){
                arrReturnElements.push(oElement);
            }
        }
        return (arrReturnElements)
    }
    function hideAll(elems) {
      for (var e = 0; e < elems.length; e++) {
        elems[e].style.display = 'none';
      }
    }
    window.onload = function() {
      hideAll(getElementsByClassName(document, 'table', 'vars'));
      hideAll(getElementsByClassName(document, 'ol', 'pre-context'));
      hideAll(getElementsByClassName(document, 'ol', 'post-context'));
    }
    function toggle() {
      for (var i = 0; i < arguments.length; i++) {
        var e = document.getElementById(arguments[i]);
        if (e) {
          e.style.display = e.style.display == 'none' ? 'block' : 'none';
        }
      }
      return false;
    }
    function varToggle(link, id) {
      toggle('v' + id);
      var s = link.getElementsByTagName('span')[0];
      var uarr = String.fromCharCode(0x25b6);
      var darr = String.fromCharCode(0x25bc);
      s.innerHTML = s.innerHTML == uarr ? darr : uarr;
      return false;
    }
    //-->
  </script>
</head>
<body>
<div id="summary">
  <h1>${exception_type |h} at ${handler.request.path_info |h}</h1>
  <pre class="exception_value">${exception_value |h}</pre>
  <table><tr>
    <th>Python</th>
    <td>${frames[0].filename |h} in ${frames[0].function |h}, line ${frames[0].lineno}</td>
  </tr><tr>
    <th>Web</th>
    <td>${handler.request.method} ${handler.request.path_url |h}</td>
  </tr></table>
</div>
<div id="traceback">
<h2>Traceback <span>(innermost first)</span></h2>
<ul class="traceback">
%for frame in frames:
    <li class="frame">
    <code>${frame.filename |h}</code> in <code>${frame.function |h}</code>
    %if frame.context_line:
        <div class="context" id="c${frame.id}">
        %if frame.pre_context:
            <ol start="${frame.pre_context_lineno}" class="pre-context" id="pre${frame.id}">
            %for line in frame.pre_context:
                <li onclick="toggle('pre${frame.id}', 'post${frame.id}')">${line |h}</li>
            %endfor
            </ol>
        %endif
            <ol start="${frame.lineno}" class="context-line"><li onclick="toggle('pre${frame.id}', 'post${frame.id}')">${frame.context_line |h} <span>...</span></li></ol>
        %if frame.post_context:
            <ol start='${frame.lineno + 1}' class="post-context" id="post${frame.id}">
            %for line in frame.post_context:
                <li onclick="toggle('pre${frame.id}', 'post${frame.id}')">${line |h}</li>
            %endfor
            </ol>
        %endif
      </div>
    %endif
    %if frame.vars:
        <div class="commands">
        <a href='#' onclick="return varToggle(this, '${frame.id}')"><span>&#x25b6;</span> Local vars</a>
        </div>
        ${dicttable(frame.vars, kls='vars', id=('v' + str(frame.id)))}
    %endif
    </li>
%endfor
  </ul>
</div>

<div id="requestinfo">
%if len(out)>0 or len(handler.response.headers._headers)>0:
<h2>Response so far</h2>
<h3>HEADERS</h3>
${dicttable_items(handler.response.headers._headers)}

<h3>BODY</h3>
<p class="req" style="padding-bottom: 2em"><code>
${out | h}
</code></p>
%endif
<h2>Request information</h2>

<h3 id="get-info">GET</h3>
${dicttable(handler.request.GET)}

<h3 id="post-info">POST</h3>
${dicttable(handler.request.POST)}

<h3 id="cookie-info">COOKIES</h3>
${dicttable(handler.request.cookies)}

<h3 id="meta-info">ENVIRON</h3>
${dicttable(handler.request.environ)}
</div>

<div id="explanation">
  <p>
    You're seeing this error because you have <code>debug</code>
    set to <code>True</code>. Set that to <code>False</code> if you don't to see this.
  </p>
</div>

</body>
</html>